﻿using Paas.Pioneer.Domain.Shared.Dto.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Paas.Pioneer.Admin.Core.HttpApi.Client.ServiceProxies;
using Volo.Abp.Application.Services;
using Volo.Abp;
using Paas.Pioneer.Domain.Shared.Dto.Output;
using Paas.Pioneer.IOTNetworkCard.Domain.NetworkCard;
using Paas.Pioneer.IOTNetworkCard.Application.Contracts.NetworkCard;
using Paas.Pioneer.IOTNetworkCard.Application.Contracts.NetworkCard.Dto.Input;
using Paas.Pioneer.IOTNetworkCard.Application.Contracts.NetworkCard.Dto.Output;
using Paas.Pioneer.IOTNetworkCard.RequestFactory.Context;
using Paas.Pioneer.IOTNetworkCard.Domain.CarrierOperator;
using Paas.Pioneer.IOTNetworkCard.RequestFactory.Context.Enum;
using Paas.Pioneer.IOTNetworkCard.RequestFactory.Dto.Input;
using Paas.Pioneer.IOTNetworkCard.Application.Contracts.CarrierOperator.Dto.Input;
using Paas.Pioneer.IOTNetworkCard.RequestFactory.Dto.Output;
using Volo.Abp.Domain.Repositories;

namespace Paas.Pioneer.IOTNetworkCard.Application.NetworkCard
{
    /// <summary>
    /// 网卡管理服务
    /// </summary>
    public class NetworkCardService : ApplicationService, INetworkCardService
    {
        private readonly INetworkCardRepository _networkCardRepository;
        private readonly IDictionaryServiceProxy _dictionaryServiceProxy;
        private readonly ICarrierOperatorRepository _carrierOperatorRepository;
        private readonly ContextRequestFactory _contextRequestFactory;

        /// <summary>
        /// 构造函数
        /// </summary>
        public NetworkCardService(INetworkCardRepository networkCardRepository,
            IDictionaryServiceProxy dictionaryServiceProxy,
            ICarrierOperatorRepository carrierOperatorRepository,
            ContextRequestFactory contextRequestFactory
        )
        {
            _networkCardRepository = networkCardRepository;
            _dictionaryServiceProxy = dictionaryServiceProxy;
            _carrierOperatorRepository = carrierOperatorRepository;
            _contextRequestFactory = contextRequestFactory;
        }

        /// <summary>
        /// 查询网卡管理
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task<GetNetworkCardOutput> GetAsync(Guid id)
        {
            var result = await _networkCardRepository.GetAsync(p => p.Id == id, x => new GetNetworkCardOutput()
            {
                ICCID = x.ICCID,
                AccessPhone = x.AccessPhone,
                EmptyPhone = x.EmptyPhone,
                IMEI = x.IMEI,
                WalletBalance = x.WalletBalance,
                GiftBalance = x.GiftBalance,
                CarrierOperatorId = x.CarrierOperatorId,
                CarrierOperatorPackageDictionaryId = x.CarrierOperatorPackageDictionaryId,
                IsApiRecharge = x.IsApiRecharge,
                IsPollingCard = x.IsPollingCard,
                ImportCardId = x.ImportCardId,
                Status = x.Status,
                IsRealName = x.IsRealName,
                IsChanneling = x.IsChanneling,
                Remark = x.Remark,
                LastModificationTime = x.LastModificationTime,
                CreationTime = x.CreationTime,
                Id = x.Id,
            });
            return result;
        }

        /// <summary>
        /// 查询分页网卡管理
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<Page<GetNetworkCardPageListOutput>> GetPageListAsync(
            PageInput<GetNetworkCardPageListInput> input)
        {
            var data = await _networkCardRepository.GetResponseOutputPageListAsync(x => new GetNetworkCardPageListOutput
            {
                ICCID = x.ICCID,
                AccessPhone = x.AccessPhone,
                EmptyPhone = x.EmptyPhone,
                IMEI = x.IMEI,
                WalletBalance = x.WalletBalance,
                GiftBalance = x.GiftBalance,
                CarrierOperatorId = x.CarrierOperatorId,
                CarrierOperatorPackageDictionaryId = x.CarrierOperatorPackageDictionaryId,
                IsApiRecharge = x.IsApiRecharge,
                IsPollingCard = x.IsPollingCard,
                ImportCardId = x.ImportCardId,
                Status = x.Status,
                IsRealName = x.IsRealName,
                IsChanneling = x.IsChanneling,
                Remark = x.Remark,
                LastModificationTime = x.LastModificationTime,
                CreationTime = x.CreationTime,
                Id = x.Id,
            }, input: input);

            if (data.Total == 0)
            {
                return data;
            }

            var carrierOperatorDictionaryList =
                await _dictionaryServiceProxy.GetListAsync(data.List.Select(x => x.CarrierOperatorPackageDictionaryId)
                    .Distinct());
            foreach (var item in data.List)
            {
                item.CarrierOperatorDictionaryName = carrierOperatorDictionaryList
                    ?.FirstOrDefault(x => x.Id == item.CarrierOperatorPackageDictionaryId)?.Name;
            }

            return data;
        }

        /// <summary>
        /// 新增网卡管理
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task AddAsync(AddNetworkCardInput input)
        {
            var networkCard = ObjectMapper.Map<AddNetworkCardInput, NetworkCardEntity>(input);
            await _networkCardRepository.InsertAsync(networkCard);
        }

        /// <summary>
        /// 修改网卡管理
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task UpdateAsync(UpdateNetworkCardInput input)
        {
            var entity = await _networkCardRepository.GetAsync(input.Id);
            if (entity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            ObjectMapper.Map(input, entity);
            await _networkCardRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除网卡管理
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public async Task DeleteAsync(Guid id)
        {
            await _networkCardRepository.DeleteAsync(m => m.Id == id);
        }

        /// <summary>
        /// 批量删除网卡管理
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns></returns>
        public async Task BatchSoftDeleteAsync(IEnumerable<Guid> ids)
        {
            await _networkCardRepository.DeleteAsync(x => ids.Contains(x.Id));
        }

        /// <summary>
        /// 停机保号/复机/测试期去激活
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<DisabledNumberOutDto> ShutDownOrResumeOrTestActivationAsync(
            UpShutDownOrResumeOrTestActivationInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });

            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));
            var disabledNumberDto = new DisabledNumberDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                OrderTypeId = (int)input.orderTypeId,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey
            };
            var disabledNumberOutDto = await requestFactory.DisabledNumberAsync(disabledNumberDto);
            if (disabledNumberOutDto != null && disabledNumberOutDto.Result != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{disabledNumberOutDto.ResultMsg}");
            }

            return disabledNumberOutDto;
        }

        /// <summary>
        /// 机卡重绑
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<IMEIReRecOrdDtoOutDto> IMEIReRecOrd(UpIMEIReRecOrdInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            if (input.bind_type == 2 && string.IsNullOrWhiteSpace(input.imei))
            {
                throw new BusinessException("请传入需要绑定的设备号！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });

            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));

            var iMEIReRecOrdDto = new IMEIReRecOrdDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey,
                Bind_Type = input.bind_type.ToString(),
                Imei = input.imei,
            };

            var iMEIReRecOrdDtoOutDto = await requestFactory.IMEIReRecOrdAsync(iMEIReRecOrdDto);
            if (iMEIReRecOrdDtoOutDto != null && iMEIReRecOrdDtoOutDto.result != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{iMEIReRecOrdDtoOutDto.resultMsg}");
            }

            return iMEIReRecOrdDtoOutDto;
        }

        /// <summary>
        /// 流量总使用量查询(时间段)
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<QueryTrafficByDateOutDto> QueryTrafficByDate(UpQueryTrafficByDateInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });


            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));

            var queryTrafficByDateDto = new QueryTrafficByDateDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey,
                StartDate = input.startDate,
                EndDate = input.endDate,
                NeedDtl = input.needDtl.ToString(),
            };

            var queryTrafficByDateOutDto = await requestFactory.QueryTrafficByDateAsync(queryTrafficByDateDto);
            if (queryTrafficByDateOutDto.IRESULT != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{queryTrafficByDateOutDto.IRESULT}");
            }

            return queryTrafficByDateOutDto;
        }

        /// <summary>
        /// 接入号码查询接口
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<GetTelephoneOutDto> GetTelephone(GetTelephoneInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });


            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));

            var getTelephoneDto = new GetTelephoneDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey,
                IDCard = "",
                ICCID = networkCardEntity.ICCID,
            };

            var fetTelephoneAsyncOutDto = await requestFactory.GetTelephoneAsync(getTelephoneDto);
            if (fetTelephoneAsyncOutDto.RESULT != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{fetTelephoneAsyncOutDto.SMSG}");
            }

            return fetTelephoneAsyncOutDto;
        }

        /// <summary>
        /// 产品资料查询接口
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<ProdInstQueryOutDto> ProdInstQuery(ProdInstQueryInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });


            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));

            var prodInstQueryDto = new ProdInstQueryDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey,
            };

            var prodInstQueryOutDto = await requestFactory.ProdInstQueryAsync(prodInstQueryDto);
            if (prodInstQueryOutDto.SvcCont.resultCode != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{prodInstQueryOutDto.SvcCont.resultMsg}");
            }

            return prodInstQueryOutDto;
        }

        /// <summary>
        /// 欠费查询接口
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<QueryOweOutDto> QueryOwe(QueryOweInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });


            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));

            var queryOweDto = new QueryOweDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey,
            };

            var queryOweOutDto = await requestFactory.QueryOweAsync(queryOweDto);
            if (queryOweOutDto.SvcCont.Service_Result_Code != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{queryOweOutDto.SvcCont.Service_Result_Code}");
            }

            return queryOweOutDto;
        }

        /// <summary>
        /// SIM卡列表查询接口
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<GetSIMListOutDto> GetSIMList(GetSIMListInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });


            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));

            var getSIMListDto = new GetSIMListDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey,
                pageIndex = input.pageIndex,
                activationTimeBegin = input.activationTimeBegin,
                activationTimeEnd = input.activationTimeEnd,
                simStatus = input.simStatus,
                groupId = input.groupId,
                ICCID = networkCardEntity.ICCID,
            };

            var getSIMListOutDto = await requestFactory.GetSIMListAsync(getSIMListDto);
            if (getSIMListOutDto.resultCode != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{getSIMListOutDto.resultMsg}");
            }

            return getSIMListOutDto;
        }

        /// <summary>
        /// 流量总使用量查询(当月)
        /// </summary>
        /// <param name="input">入参</param>
        /// <returns></returns>
        public async Task<QueryTrafficOutDto> QueryTraffic(QueryTrafficInput input)
        {
            var networkCardEntity = await _networkCardRepository.GetAsync(input.NetworkCardId);
            if (networkCardEntity?.Id == Guid.Empty)
            {
                throw new BusinessException("数据不存在！");
            }

            var carrierOperatorEntity = await _carrierOperatorRepository.GetAsync(networkCardEntity.CarrierOperatorId);
            var getDictionaryOutputs =
                await _dictionaryServiceProxy.GetListAsync(new List<Guid>() { carrierOperatorEntity.DictionaryId });


            var requestFactory =
                _contextRequestFactory.GetRequestFactory(
                    (EContextRequestType)(int.Parse(getDictionaryOutputs.FirstOrDefault()?.Value ??
                                                    throw new InvalidOperationException())));

            var queryTrafficDto = new QueryTrafficDto()
            {
                Account = carrierOperatorEntity.Account,
                AccessNumber = networkCardEntity.AccessPhone,
                Password = carrierOperatorEntity.Password,
                SecretKey = carrierOperatorEntity.SecretKey,
                NeedDtl = input.needDtl.ToString(),
            };

            var queryTrafficOutDto = await requestFactory.QueryTrafficAsync(queryTrafficDto);
            if (queryTrafficOutDto.IRESULT != "0")
            {
                throw new BusinessException($"接口请求失败,原因:{queryTrafficOutDto.IRESULT}");
            }

            return queryTrafficOutDto;
        }

        public async Task<BindIccidOutput> BindIccidAsync(string iccid)
        {
            var networkCard =
                await _networkCardRepository.FirstOrDefaultAsync(x => x.ICCID == iccid || x.AccessPhone == iccid);
            if (networkCard == null)
            {
                throw new BusinessException("ICCID或接入号码 不存在");
            }

            networkCard.UserId = CurrentUser.Id.Value;

            return await _carrierOperatorRepository.GetAsync(expression: x => x.Id == networkCard.CarrierOperatorId,
                selector: x => new BindIccidOutput
                {
                    IsBindMobile = x.IsBindPhone
                });
        }
    }
}